/* ** por compatibilidad se omiten tildes **
================================================================================
 TRABAJO PRACTICO 3 - System Programming - ORGANIZACION DE COMPUTADOR II - FCEN
================================================================================
  definicion de la tabla de descriptores globales
*/
#include "defines.h"

#include "gdt.h"
#include "tss.h"

gdt_entry gdt[GDT_COUNT] = {
	/* Descriptor nulo*/
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //0
	
	//Primer Descriptor Nulo
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //1
	
	//Ponemos Descriptor Nulo hasta el noveno descriptor (las primeras 10 posiciones se consideran utilizadas)
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //2
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //3
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //4
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //5
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //6
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //7
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //8
	(gdt_entry){(unsigned int) 0x00000000, (unsigned int) 0x00000000 }, //9
	
	//Codigo Nivel 0
	(gdt_entry){
		(unsigned short) 0xFFFF,	//limit_0_15 (2GB - 1 = 524288 KB - 1 =  0111 1111 1111 1111 1111 en Binario)
		(unsigned short) 0x0000, 	//base_0_15
		(unsigned char) 0x00, 		//base_23_16
		(unsigned char) 0xA, 		//type:4 	= 0xA (Code: Execute/Read)
		(unsigned char) 1, 		//s:1 		= 1 (code or data)
		(unsigned char) 0, 		//dpl:2 	= 0 (Nivel 0)
		(unsigned char) 1, 		//p:1		= 1 (Presente)
		(unsigned char) 0x7,		//limit_16_19:4
		(unsigned char) 0,  		//avl:1
		(unsigned char) 0,  		//l:1		= 0 (IA-32e mode only)
		(unsigned char) 1,  		//db:1		= 1 (32-bit segmento)
		(unsigned char) 1, 		//g:1		= Granularity
		(unsigned char) 0x00 		//base_31_24
	},//10 0x50

	//Codigo Nivel 3
	(gdt_entry){
		(unsigned short) 0xFFFF,	//limit_0_15 (2GB - 1 = 524288 KB - 1 = 0111 1111 1111 1111 1111 en Binario)
		(unsigned short) 0x0000, 	//base_0_15
		(unsigned char) 0x00, 		//base_23_16
		(unsigned char) 0xA, 		//type:4 	= 0xA (Code: Execute/Read)
		(unsigned char) 1, 		//s:1 		= 1 (code or data)
		(unsigned char) 0x3, 		//dpl:2 	= 3 (Nivel 3)
		(unsigned char) 1, 		//p:1		= 1 (Presente)
		(unsigned char) 0x7,		//limit_16_19:4
		(unsigned char) 0,  		//avl:1
		(unsigned char) 0,  		//l:1		= 0 (IA-32e mode only)
		(unsigned char) 1,  		//db:1		= 1 (32-bit segmento)
		(unsigned char) 1, 		//g:1		= Granularity
		(unsigned char) 0x00 		//base_31_24
	},//11 0x58
	
	//Datos Nivel 0
	(gdt_entry){
		(unsigned short) 0xFFFF,	//limit_0_15 (2GB - 1 = 524288 KB - 1 = 0111 1111 1111 1111 1111 en Binario)
		(unsigned short) 0x0000, 	//base_0_15
		(unsigned char) 0x00, 		//base_23_16
		(unsigned char) 0x2, 		//type:4 	= 0x2 (Data: Read/Write)
		(unsigned char) 1, 		//s:1 		= 1 (code or data)
		(unsigned char) 0, 		//dpl:2 	= 0 (Nivel 0)
		(unsigned char) 1, 		//p:1		= 1 (Presente)
		(unsigned char) 0x7,		//limit_16_19:4
		(unsigned char) 0,  		//avl:1
		(unsigned char) 0,  		//l:1		= 0 (IA-32e mode only)
		(unsigned char) 1,  		//db:1		= 1 (32-bit segmento)
		(unsigned char) 1, 		//g:1		= Granularity
		(unsigned char) 0x00 		//base_31_24
	},//12 0x60
	
	//Datos Nivel 3
	(gdt_entry){
		(unsigned short) 0xFFFF,	//limit_0_15 (2GB - 1 = 524288 KB - 1 = 0111 1111 1111 1111 1111 en Binario)
		(unsigned short) 0x0000, 	//base_0_15
		(unsigned char) 0x00, 		//base_23_16
		(unsigned char) 0x2, 		//type:4 	= 0x2 (Data: Read/Write)
		(unsigned char) 1, 		//s:1 		= 1 (code or data)
		(unsigned char) 0x3, 		//dpl:2 	= 3 (Nivel 3)
		(unsigned char) 1, 		//p:1		= 1 (Presente)
		(unsigned char) 0x7,		//limit_16_19:4
		(unsigned char) 0,  		//avl:1
		(unsigned char) 0,  		//l:1		= 0 (IA-32e mode only)
		(unsigned char) 1,  		//db:1		= 1 (32-bit segmento)
		(unsigned char) 1, 		//g:1		= Granularity
		(unsigned char) 0x00 		//base_31_24
	},//13 0x68
	
	//Datos (Video) Nivel 0
	(gdt_entry){
		(unsigned short) 0x0F9F,	//limit_0_15 (80 col x 25 filas x 2byte c/elem. - 1(contamos el cero)  = 3999 Bytes = 1111 1001 1111 en Binario)
		(unsigned short) 0x8000, 	//base_0_15 = B8000 
		(unsigned char) 0x0B, 		//base_23_16
		(unsigned char) 0x2, 		//type:4 	= 0x2 (Data: Read/Write)
		(unsigned char) 1, 		//s:1 		= 1 (code or data)
		(unsigned char) 0, 		//dpl:2 	= 0 (Nivel 0)
		(unsigned char) 1, 		//p:1		= 1 (Presente)
		(unsigned char) 0x0,		//limit_16_19:4
		(unsigned char) 0,  		//avl:1
		(unsigned char) 0,  		//l:1		= 0 (IA-32e mode only)
		(unsigned char) 1,  		//db:1		= 1 (32-bit segmento)
		(unsigned char) 0, 		//g:1		= Granularity
		(unsigned char) 0x00 		//base_31_24
	},//14 0x70
	
};

void setear_descriptor_tss_GDT(unsigned int indice_gdt, tss* _tss, unsigned int nivel)
{
	gdt_entry* entrada_gdt = (gdt_entry*)gdt;
	entrada_gdt += indice_gdt;	//Nos paramos en el indice de la gdt para poner el descriptor TSS

	entrada_gdt->limit_0_15 = (unsigned short) 0x67; // 0x67 = 103 que es el tamaño (104-1) del Task Segment
	entrada_gdt->base_0_15 	= (unsigned short)((unsigned int)_tss);	//Tomamos los primeros 16 bits de la base
	entrada_gdt->base_23_16 = (unsigned char) (((unsigned int)_tss) >> 16); //tomamos los ultimos 8 bits de la base
	entrada_gdt->type = 0x9; // 10B1, donde B es el de Busy, como solo estamos inicializando en la gdt le ponemos 0 => 1001 = 0x9
	entrada_gdt->s = 0;	
	entrada_gdt->dpl = nivel;//Nivel 3 para las tareas y Nivel 0 para la tarea idle e inicial
	entrada_gdt->p = 1;	//presente
	entrada_gdt->limit_16_19 = 0x0;
	entrada_gdt->avl = 0;
	entrada_gdt->l = 0;	
	entrada_gdt->db = 1;  
	entrada_gdt->g = 0;	
	entrada_gdt->base_31_24 = (unsigned char) ((unsigned int)_tss >> 24);
}


gdt_descriptor GDT_DESC = {sizeof(gdt)-1, (unsigned int)&gdt};
